#include <buola/gui/x11/auto.h>

#include <buola/gui/x11/cglxinterface.h>
#include <buola/gui/x11/cx11window.h>
#include <buola/gui/x11/cx11drawable.h>
#include <buola/gui/x11/cx11display.h>
#include <buola/image/csurface.h>
#include <buola/gui/x11/cvisual.h>

namespace buola { namespace gui { namespace x11 {

static void ATTRIBUTE_UNUSED PrintFBConfig(io::CTextWriter &pWriter,GLXFBConfig pConfig)
{
    struct SEntry
    {
        const char *mName;
        int mIndex;
    };

    SEntry lEntries[]=
    {
        {   "GLX_VISUAL_ID         ",   GLX_VISUAL_ID       },
        {   "GLX_FBCONFIG_ID       ",   GLX_FBCONFIG_ID     },
        {   "GLX_X_RENDERABLE      ",   GLX_X_RENDERABLE    },
        {   "GLX_ALPHA_SIZE        ",   GLX_ALPHA_SIZE      },
        {   "GLX_SAMPLE_BUFFERS    ",   GLX_SAMPLE_BUFFERS  },
        {   "GLX_SAMPLES           ",   GLX_SAMPLES         },
        {   nullptr,                       0                   }
    };

    pWriter << "Info about FBConfig:\n";
    for(int i=0;lEntries[i].mName;i++)
    {
        int lValue;
        glXGetFBConfigAttrib(get_default_x11_display()->GetDisplay(),pConfig,
                        lEntries[i].mIndex,&lValue);

        pWriter << "   " << lEntries[i].mName << lValue << "\n";
    }
}

CGLXInterface::CGLXInterface(CX11Window *pDrawable)
    :   mVisualInfo(nullptr)
{
    CVisual lVisual(pDrawable);

    if(CGLX::GetVersion()>=GLX_SERVERVERSION(1,3))
    {
        int lAttribList[]=
        {
#ifdef HAVE_NVIDIA_OPENGL
            GLX_VISUAL_ID,          (int)lVisual.GetID(),
#endif
            0
        };

        int lCount;
        GLXFBConfig *lList=glXChooseFBConfig(get_default_x11_display()->GetDisplay(),
                                             get_default_x11_display()->GetScreenNumber(),lAttribList,&lCount);

        int lWhich=-1;

        for(int i=0;i<lCount;i++)
        {
//          PrintFBConfig(lList[i]);
            int lValue;
            glXGetFBConfigAttrib(get_default_x11_display()->GetDisplay(),lList[i],
                            GLX_VISUAL_ID,&lValue);
            if(lValue==lVisual.GetID())
                lWhich=i;
        }

        if(lWhich<0)
        {
            throw XNotFound("didn't find any valid FBConfig\n");
        }

        mFBConfig=lList[lWhich];

        mDrawable=glXCreateWindow(get_default_x11_display()->GetDisplay(),mFBConfig,pDrawable->GetX11ID(),nullptr);
    }
    else
    {
        mVisualInfo=lVisual.GetVisualInfo(true);
        mDrawable=pDrawable->GetX11ID();
    }
}

CGLXInterface::~CGLXInterface()
{
    if(CGLX::GetVersion()>=GLX_SERVERVERSION(1,3))
    {
        glXDestroyWindow(get_default_x11_display()->GetDisplay(),mDrawable);
    }

    if(mVisualInfo)
        XFree(mVisualInfo);
}

/*namespace x11*/ } /*namespace gui*/ } /*namespace buola*/ }
